{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3.3. 将课程内容转为PPT\n",
    "\n",
    "## 🚄 前言\n",
    "在实际授课过程中，常常需要制作PPT以辅助讲解。本节课程介绍如何借助文本生成模型 Qwen-Max 和基于 Markdown 的演示文稿生成工具 Marp，将课程内容快速转换为 PPT。\n",
    "\n",
    "## 🍁 课程目标\n",
    "学完本课程后，你将能够：\n",
    "- 使用 Qwen-Max 进行内容提炼和格式转换\n",
    "- 了解 Marp，并使用 Marp 将 Mardkown 文档导出为 PPT\n",
    "\n",
    "## 📖 课程目录\n",
    "\n",
    "- [1. 原理介绍](#🧮-1-原理介绍)\n",
    "- [2. 代码实践](#🛠️-2-代码实践)\n",
    "    - [2.1. 环境准备](#21-环境准备)\n",
    "    - [2.2. 设置 API 客户端](#22-设置-api-客户端)\n",
    "    - [2.3. 从课程内容中提炼出 PPT 脚本](#23-从课程内容中提炼出-ppt-脚本)\n",
    "    - [2.4. 将 PPT 脚本转换为 Marp 格式](#24-将-ppt-脚本转换为-marp-格式)\n",
    "    - [2.5. 导出为 PPT](#25-导出为-ppt)\n",
    "  \n",
    "\n",
    "## 🧮 1. 原理介绍\n",
    "\n",
    "为了将课程内容转换成 PPT，除了大模型，我们还需要结合使用一款工具：\n",
    "\n",
    "- [Marp](https://github.com/marp-team/marp)： 一个基于 Markdown 的幻灯片生成工具，旨在简化创建演示文稿的过程。它允许用户使用轻量级的 Markdown 语法编写幻灯片，生成美观的演示，无需使用复杂的幻灯片编辑器。这使得 Marp 特别适合技术人员、开发者和喜欢使用 Markdown 的用户。\n",
    "\n",
    "\n",
    "结合使用 Qwen-Max 和 Marp 将课程内容转为 PPT 的过程如下：\n",
    "\n",
    "<div align=\"center\">\n",
    "    <img src=\"https://gw.alicdn.com/imgextra/i1/O1CN01ywrWDR1dI9CB5NFFR_!!6000000003712-0-tps-2398-190.jpg\" alt=\"流程\" width=\"80%\"/>\n",
    "</div>\n",
    "\n",
    "\n",
    "## 🛠️ 2. 代码实践\n",
    "\n",
    "接下来，让我们运行以下代码，将第一节课生成的课程内容转换为 PPT。\n",
    "\n",
    "### 2.1. 环境准备"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 安装 Python 库工具。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecutionIndicator": {
     "show": false
    },
    "execution": {
     "iopub.execute_input": "2024-09-29T10:24:48.713758Z",
     "iopub.status.busy": "2024-09-29T10:24:48.713457Z",
     "iopub.status.idle": "2024-09-29T10:24:52.610896Z",
     "shell.execute_reply": "2024-09-29T10:24:52.610338Z",
     "shell.execute_reply.started": "2024-09-29T10:24:48.713741Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "! pip install -r requirements.txt -q"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 你需要安装一些依赖项以完成后面的工作。\n",
    "\n",
    "首先请安装 marp cli 库，这一步可能会**需要一些时间**，一般十分钟左右会完成，如果卡在某个进度，请尝试（🛑）终止进程重新执行。\n",
    "\n",
    "如果这里的 marp cli 安装不成功，请检查网络链接，尝试切换到命令行状态安装。\n",
    "\n",
    "运行以下代码来安装依赖项。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 安装marp cli\n",
    "! npm install -g @marp-team/marp-cli -y -qq"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3. 导入必要的模块。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecutionIndicator": {
     "show": false
    },
    "execution": {
     "iopub.execute_input": "2024-09-29T10:24:52.612233Z",
     "iopub.status.busy": "2024-09-29T10:24:52.611961Z",
     "iopub.status.idle": "2024-09-29T10:24:52.614902Z",
     "shell.execute_reply": "2024-09-29T10:24:52.614498Z",
     "shell.execute_reply.started": "2024-09-29T10:24:52.612215Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import openai\n",
    "import json\n",
    "from typing import Union\n",
    "import subprocess\n",
    "from utils import read_text_from_file, save_file,load_config"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4. 设置环境变量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "sys.path.append(\"../\")\n",
    "from config.load_key import load_key\n",
    "load_key()\n",
    "print(os.environ[\"DASHSCOPE_API_KEY\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "5. 加载配置文件。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2024-09-29T10:24:52.615743Z",
     "iopub.status.busy": "2024-09-29T10:24:52.615531Z",
     "iopub.status.idle": "2024-09-29T10:24:52.619020Z",
     "shell.execute_reply": "2024-09-29T10:24:52.618639Z",
     "shell.execute_reply.started": "2024-09-29T10:24:52.615729Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "project_config = load_config(\"config.json\")\n",
    "title = project_config[\"title\"]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "### 2.2. 设置 API 客户端\n",
    "设置 OpenAI 的 API 客户端，用于后续调用阿里云百炼的 Qwen-Max 模型和 Flux-Merged 模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2024-09-29T10:24:53.489315Z",
     "iopub.status.busy": "2024-09-29T10:24:53.489002Z",
     "iopub.status.idle": "2024-09-29T10:24:53.538090Z",
     "shell.execute_reply": "2024-09-29T10:24:53.537633Z",
     "shell.execute_reply.started": "2024-09-29T10:24:53.489297Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "client = openai.OpenAI(\n",
    "    api_key=os.getenv(\"DASHSCOPE_API_KEY\"),\n",
    "    base_url=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "### 2.3. 从课程内容中提炼出 PPT 脚本\n",
    "\n",
    "首先，我们让文本生成模型 Qwen-Turbo 扮演一位 PPT 专家，从详细的课程内容中提炼出用于演示的内容要点。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 定义一个 `create_ppt_script` 函数，用于使用 Qwen-Turbo 将课程内容从源语言直接翻译为目标语言。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2024-09-29T10:24:54.551696Z",
     "iopub.status.busy": "2024-09-29T10:24:54.551410Z",
     "iopub.status.idle": "2024-09-29T10:24:54.556512Z",
     "shell.execute_reply": "2024-09-29T10:24:54.556091Z",
     "shell.execute_reply.started": "2024-09-29T10:24:54.551678Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def create_ppt_script(course_script):\n",
    "    system_message = \"你是一位专业的 PPT 专家，专注于根据课程脚本开发教学 PPT。\"\n",
    "\n",
    "    prompt = (\n",
    "        f\"将以下课程脚本转换为 PPT 格式：\\n\\n\"\n",
    "        f\"{course_script}\\n\\n\"\n",
    "        \"请遵循以下指导原则：\\n\"\n",
    "        \"保持原有的章节结构，注意标题页和总结页，此外中间的页面不要额外生成内容。\"\n",
    "        \"仅生成PPT框架的内容。结尾不要写任何寄语，会被当作一个新的片段。在ppt里不要写任何备注。\"\n",
    "        \"1. **提炼关键信息**：避免冗长段落。\\n\"\n",
    "        \"2. **使用简短标题**：聚焦于要点。\\n\"\n",
    "        \"3. **内容简洁明了**：去除多余信息。\\n\"\n",
    "        \"4. **结合图片辅助**：在适当的位置插入图片。\\n\"\n",
    "        \"5. **不新增内容**：确保不添加任何额外信息。\\n\"\n",
    "\n",
    "        \"格式要求：\\n\"\n",
    "        \"1. 正文使用清晰的有序和无序列表：有序列表用于顺序内容，无序列表用于其它内容。\\n\"\n",
    "        \"2. 确保代码片段格式规范。\\n\"\n",
    "        \"3. 输出必须是 Markdown 格式。\\n\\n\"\n",
    "        \"\\n 不要输出 ### 三级标题\\n\"\n",
    "        \"\\n 遵照原文不要生成新的 ## 二级标题\\n\"\n",
    "        \"4. 允许使用 1 级和 2 级标题，禁止出现 3 级及以上标题。\\n\"\n",
    "        \"5. 输出中不得包含 ```markdown 和 ```。\\n\"\n",
    "        \"6. 图片不显示为列表。\\n\"\n",
    "\n",
    "        \"输出要求：\\n\"\n",
    "        \"输出应仅包含 Markdown 格式的 PPT 脚本，禁止任何解释性文字。\\n\"\n",
    "        \"示例输出格式：\\n\"\n",
    "        \"# 云计算深入探索\\n\"\n",
    "        \"![云计算深入探索](https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/1d/2c/20240923/f1ceb422/56a52df0-426f-4352-bbf6-40ffeb1cb04e-1.png?Expires=1727165843&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=YaCArgLeSs4y3SLcROEBfiUnACc%3D)\\n\"\n",
    "        \"## 什么是云计算？\\n\"\n",
    "        \"- 通过互联网提供服务\\n\"\n",
    "        \"- 按需获取\\n\"\n",
    "        \"- 按量付费\\n\"\n",
    "        \"![什么是云计算](https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/1d/aa/20240923/f1ceb422/8681083c-c304-45fd-af78-ecb68174561d-1.png?Expires=1727165862&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=I3MMGZA3mcQWZ24yz7qkdPl5G2Y%3D)\\n\"\n",
    "    )\n",
    "\n",
    "    # 直接调用 API 获取课程脚本\n",
    "    completion = client.chat.completions.create(\n",
    "        model=\"qwen-max\",\n",
    "        messages=[\n",
    "            {\"role\": \"system\", \"content\": system_message},\n",
    "            {\"role\": \"user\", \"content\": prompt},\n",
    "        ],\n",
    "    )\n",
    "\n",
    "    # 如果 model_dump_json() 返回字符串需要解析为 JSON\n",
    "    dumped_json = json.loads(completion.model_dump_json())\n",
    "\n",
    "    # 使用正确的属性访问生成的内容\n",
    "    return dumped_json['choices'][0]['message']['content']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 调用 `create_ppt_script` 函数，从课程脚本中提炼出 PPT 脚本。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2024-09-29T10:24:56.753385Z",
     "iopub.status.busy": "2024-09-29T10:24:56.753066Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "成功读取文件：./output/course_script_with_illustrations/云计算_含插画课程脚本.md\n",
      "```markdown\n",
      "# 云计算基础课程\n",
      "## 什么是云计算？\n",
      "- 计算资源互联网提供\n",
      "- 需求驱动，即时扩展\n",
      "- 按需付费，成本效率\n",
      "\n",
      "![云计算比喻](../illustrations/云计算比喻.png)\n",
      "\n",
      "## 云计算核心优势\n",
      "### 灵活性与可扩展性\n",
      "- 快速调整服务规模\n",
      "\n",
      "![灵活变形车](../illustrations/灵活变形车.png)\n",
      "\n",
      "### 成本效益\n",
      "- 减少硬件投资\n",
      "\n",
      "![租房vs买房](../illustrations/租房vs买房.png)\n",
      "\n",
      "### 易于管理\n",
      "- 服务商管理基础架构\n",
      "\n",
      "![超级管家](../illustrations/超级管家.png)\n",
      "\n",
      "## 服务模型\n",
      "### IaaS (基础设施即服务)\n",
      "- 计算、存储、网络资源\n",
      "\n",
      "![IaaS厨房](../illustrations/IaaS厨房.png)\n",
      "\n",
      "### PaaS (平台即服务)\n",
      "- 包含开发工具与数据库\n",
      "\n",
      "![PaaS半成品](../illustrations/PaaS半成品.png)\n",
      "\n",
      "### SaaS (软件即服务)\n",
      "- 完整应用，浏览器访问\n",
      "\n",
      "![SaaS外卖](../illustrations/SaaS外卖.png)\n",
      "\n",
      "## 云部署模式\n",
      "### 公有云\n",
      "- 第三方提供，公众访问\n",
      "\n",
      "![公有云商场](../illustrations/公有云商场.png)\n",
      "\n",
      "### 私有云\n",
      "- 专为企业，内部使用\n",
      "\n",
      "![私有云会所](../illustrations/私有云会所.png)\n",
      "\n",
      "### 混合云\n",
      "- 结合公有与私有云优势\n",
      "\n",
      "![混合云冰箱超市](../illustrations/混合云冰箱超市.png)\n",
      "```\n",
      "请注意，上述Markdown格式的PPT脚本已根据您的要求进行调整，包含了1级和2级标题，没有新增任何内容，并且整合了图片引用。\n",
      "目标目录：./output/ppt_script\n",
      "文件路径：./output/ppt_script/云计算_幻灯片脚本.md\n",
      "文件已成功保存为：./output/ppt_script/云计算_幻灯片脚本.md\n"
     ]
    }
   ],
   "source": [
    "# 从指定目录读取首个文件内容\n",
    "course_script_file = project_config[\"course_script_with_illustrations_file_path\"].format(title=project_config[\"title\"])\n",
    "\n",
    "# 读取课程脚本\n",
    "course_script = read_text_from_file(course_script_file)\n",
    "\n",
    "# 确保课程脚本不为空\n",
    "if not course_script:\n",
    "    raise ValueError(\"课程脚本为空，无法生成 PPT。\")\n",
    "\n",
    "# 调用函数生成 PPT 脚本\n",
    "ppt_script = create_ppt_script(course_script)\n",
    "print(ppt_script)\n",
    "\n",
    "# 构造文件名\n",
    "ppt_script_file_path = project_config[\"ppt_script_file_path\"].format(title=project_config[\"title\"])\n",
    "\n",
    "# 调用函数保存PPT\n",
    "save_file(ppt_script, ppt_script_file_path)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "### 2.4. 将 PPT 脚本转换为 Marp 格式\n",
    "\n",
    "接下来，我们使用 Qwen-Max，将 Markdown 格式的 PPT 脚本转换为 Marp 格式。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 定义一个 `convert_md_to_marp` 函数，用于转换 PPT 脚本为 Marp 格式。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def convert_md_to_marp(ppt_script):\n",
    "    system_message = \"你是一位专业的 Marp 专家，专注于将内容从 Markdwon 转换为 Marp 格式。\"\n",
    "\n",
    "    prompt = (\n",
    "        f\"请将以下内容转换为 Marp 格式：\\n\\n\"\n",
    "        f\"{ppt_script}\\n\\n\"\n",
    "        \"请遵循以下要求：\\n\"\n",
    "        \"1. **Marp 固定开头格式**：\\n\"\n",
    "        \"   ---\\n\"\n",
    "        \"   marp: true\\n\"\n",
    "        \"   theme: default\\n\"\n",
    "        \"   paginate: true\\n\"\n",
    "        \"   size: 16:9\\n\"\n",
    "        \"   ---\\n\"\n",
    "        \"2. **封面和封底图片**格式为：`![bg](url)`。\\n\"\n",
    "        \"3. **正文图片**格式为：`![bg left](url)` 或 `![bg right](url)`。\\n\"\n",
    "        \"4. **结尾**不得包含 `---`。\\n\"\n",
    "        \"5. **一级标题**和**二级标题**之间必须使用 `---` 分隔。\\n\"\n",
    "        \"6. 生成的内容开头和结尾不包含 ```。\\n\"\n",
    "        \"\\n输出要求：\\n\"\n",
    "        \"\\n不要输出 ### 三级标题\\n\"\n",
    "        \"\\n遵照原文不要生成新的 ## 二级标题\\n\"\n",
    "        \"输出应仅包含 Marp 格式的 PPT 脚本，不要添加其他内容。\\n\"\n",
    "        \"示例输出格式：\\n\"\n",
    "        \"---\\n\"\n",
    "        \"marp: true\\n\"\n",
    "        \"theme: default\\n\"\n",
    "        \"paginate: true\\n\"\n",
    "        \"size: 16:9\\n\"\n",
    "        \"---\\n\"\n",
    "        \"![bg](https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/1d/2c/20240923/f1ceb422/56a52df0-426f-4352-bbf6-40ffeb1cb04e-1.png?Expires=1727165843&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=YaCArgLeSs4y3SLcROEBfiUnACc%3D)\\n\"\n",
    "        \"# 云计算深入探索\\n\"\n",
    "        \"---\\n\"\n",
    "        \"![bg left](https://dashscope-result-bj.oss-cn-beijing.aliyuncs.com/1d/aa/20240923/f1ceb422/8681083c-c304-45fd-af78-ecb68174561d-1.png?Expires=1727165862&OSSAccessKeyId=LTAI5tQZd8AEcZX6KZV4G8qL&Signature=I3MMGZA3mcQWZ24yz7qkdPl5G2Y%3D)\\n\"\n",
    "        \"## 什么是云计算？\\n\"\n",
    "        \"- 通过互联网提供服务\\n\"\n",
    "        \"- 按需获取\\n\"\n",
    "        \"- 按量付费\\n\"\n",
    "    )\n",
    "    # 直接调用 API 获取课程脚本\n",
    "    completion = client.chat.completions.create(\n",
    "        model=\"qwen-max\",\n",
    "        messages=[\n",
    "            {\"role\": \"system\", \"content\": system_message},\n",
    "            {\"role\": \"user\", \"content\": prompt},\n",
    "        ],\n",
    "    )\n",
    "\n",
    "    # 如果 model_dump_json() 返回字符串需要解析为 JSON\n",
    "    dumped_json = json.loads(completion.model_dump_json())\n",
    "\n",
    "    # 使用正确的属性访问生成的内容\n",
    "    text = dumped_json['choices'][0]['message']['content']\n",
    "    text = text.replace(\"```\\n\",\"\").replace(\"\\n```\",\"\")\n",
    "    return text"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 调用 `convert_md_to_marp` 函数转换 PPT 脚本为 Marp 格式。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecutionIndicator": {
     "show": false
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "ppt_script_file_path = project_config[\"ppt_script_file_path\"].format(title=project_config[\"title\"])\n",
    "ppt_script = read_text_from_file(ppt_script_file_path)\n",
    "\n",
    "# 确保 PPT 脚本不为空\n",
    "if not ppt_script:\n",
    "    raise ValueError(\"PPT 脚本为空，无法进行转换。\")\n",
    "\n",
    "# 调用函数生成 Marp 格式的脚本\n",
    "marp_script = convert_md_to_marp(ppt_script)\n",
    "print(marp_script)\n",
    "\n",
    "# 构造文件名\n",
    "marp_script_file_path = project_config[\"marp_script_file_path\"].format(title=project_config[\"title\"])\n",
    "\n",
    "# 保存marp文件\n",
    "save_file(marp_script, marp_script_file_path)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "### 2.5. 导出为 PPT"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.5.1. 安装依赖项\n",
    "\n",
    "**安装浏览器**\n",
    "\n",
    "你需要安装一款浏览器来完成后面的工作\n",
    "- 如果你在使用 MAC上的IDE如code，你可以确认自己的机器上是否安装了 chrome 或 firefox。如果已经安装浏览器，你可以**跳过这一步**。\n",
    "- 如果你在使用 pai-DSW 或者 modelscope-DSW，我们推荐你执行以下代码，安装linxu版本的 firefox。 \n",
    "\n",
    "你可以取消下面代码的注释来 [【安装 firefox】](https://support.mozilla.org/en-US/kb/install-firefox-linux) 以完成后面的工作。请注意，经过这一步，你应该安装了一个超过200MB的firefox。\n",
    "\n",
    "这个安装需要等待时间较长，根据网速不同可能需要几分钟到几小时。等待安装完成后就可以继续做PPT转换。\n",
    "\n",
    "> 如果你在DSW上仍然频繁遇到各种环境配置问题，可以考虑将课程代码下载到本地电脑上运行。这样，你将拥有更高的权限，并且更容易搭建所需的环境。（请参考第一章计算环境准备）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# # 如果你本机上没有安装 chrome 或 firefox，你需要取消下面代码行的注释，去掉“# ”，执行该语句可以安装浏览器firefox。\n",
    "\n",
    "# ! /bin/bash install_firefox.sh -qq"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**安装其他依赖项**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "! sudo apt-get update -qq\n",
    "# 安装依赖\n",
    "! apt-get install -y poppler-utils -qq\n",
    "\n",
    "# 安装python依赖\n",
    "! pip install pdf2image -qq"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.5.2. 生成PPT \n",
    "\n",
    "最后，我们可以使用 Marp 将生成的 Marp 格式 PPT 导出为 PPTX，用于授课时演示"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 定义一个 `export_marp_ppt` 函数，用于导出 PPT。\n",
    "\n",
    "函数内容我们保存在convert_md_pdf.py中，可以从命令行调用。\n",
    "\n",
    "2. 调用 `export_marp_ppt` 函数导出 PPT。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "marp_script_file_path = project_config[\"marp_script_file_path\"].format(title=project_config[\"title\"])\n",
    "marp_script = read_text_from_file(marp_script_file_path)\n",
    "\n",
    "# 确保 Marp 脚本不为空\n",
    "if not marp_script:\n",
    "    raise ValueError(\"Marp 脚本为空，无法生成 PPT。\")\n",
    "\n",
    "\n",
    "marp_export_folder = project_config[\"marp_export_folder\"]\n",
    "\n",
    "! python convert_md_pdf.py {marp_script_file_path}  {marp_export_folder}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### QA\n",
    "如果你在这里出现了找不到firefox浏览器的报错，你可以先请检查 2.5.1 中  ```! /bin/bash install_firefox.sh```这句是不是没有执行。去掉“# ”可以取消注释，之后您可以执行这句安装。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "tags": []
   },
   "source": [
    "## ✅ 本节小结\n",
    "\n",
    "- 在本次学习和实践中，我们使用了 Qwen-Max 进行了内容提炼和格式转换，并且使用了 Marp 将 Markdown 文件导出为 PPT。\n",
    "- 完成授课后，不少同学希望能有课程录音，便于之后随时随地复习巩固。接下来，我们将学习如何使用大模型将课程内容转换为音频。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 🔥 课后小测验\n",
    "\n",
    "【单选题】3.3.1. 你想使用 Qwen-Max 将一段冗长的课程文本提炼成简洁的 PPT 脚本要点。以下哪种 Prompt 更有效？（ ）\n",
    "\n",
    "A. \"请阅读以下文本：[文本内容] \"\n",
    "\n",
    "B. \"请将以下文本总结成 PPT 脚本要点，每页 PPT 对应一个要点：[文本内容]\"\n",
    "\n",
    "C. \"请生成一张 PPT\"\n",
    "\n",
    "D. \"使用 Marp 生成 PPT\"\n",
    "\n",
    "答案：B 选项 B 清晰地指示了 Qwen-Max 的任务和期望的输出格式，比其他选项更有效。选项 A 只是让模型阅读文本，没有明确的任务。选项 C 和 D 与提炼文本无关。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ✉️ 评价反馈\n",
    "感谢你学习阿里云大模型ACP认证课程，如果你觉得课程有哪里写得好、哪里写得不好，期待你[通过问卷提交评价和反馈](https://survey.aliyun.com/apps/zhiliao/Mo5O9vuie)。\n",
    "\n",
    "你的批评和鼓励都是我们前进的动力。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "learnacp",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
